package leader

import (
	"context"
	"fmt"
	"gitverse.ru/synapse/kubelatte/pkg/creation"
	"gitverse.ru/synapse/kubelatte/pkg/observability/logs"
	"gitverse.ru/synapse/kubelatte/pkg/operator"
	"gitverse.ru/synapse/kubelatte/pkg/operator/controllers"
	"os"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/webhook"
	"strings"
	"time"
)

func startTriggerController() {
	triggerR = &controllers.TriggerReconciler{
		Client: Mgr.GetClient(),
		Scheme: Mgr.GetScheme(),
	}

	if err := triggerR.SetupWithManager(Mgr); err != nil {
		logs.Fatal(fmt.Sprintf("Unable to create Trigger controller: %s", err.Error()))
		os.Exit(1)
	}
}

func startTemplateController() {
	templateR = &controllers.TemplateReconciler{
		Client: Mgr.GetClient(),
		Scheme: Mgr.GetScheme(),
	}

	if err := templateR.SetupWithManager(Mgr); err != nil {
		logs.Fatal(fmt.Sprintf("Unable to create Template controller: %s", err.Error()))
		os.Exit(1)
	}
}

func startScopeController() {
	scopeR = &controllers.ScopeReconciler{
		Client: Mgr.GetClient(),
		Scheme: Mgr.GetScheme(),
	}

	if err := scopeR.SetupWithManager(Mgr); err != nil {
		logs.Fatal(fmt.Sprintf("Unable to create Scope controller: %s", err.Error()))
		os.Exit(1)
	}
}

func startNamespaceController(ctx context.Context) {
	opt := ctrl.Options{
		Logger:             Mgr.GetLogger(),
		Scheme:             Mgr.GetScheme(),
		WebhookServer:      webhook.NewServer(webhook.Options{Port: 9444}),
		MetricsBindAddress: "0",
	}

	clusterMgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), opt)
	if err != nil {
		logs.Fatal(fmt.Sprintf("Problem running namespace manager: %s", err.Error()))
		os.Exit(1)
	}

	namespaceR = &controllers.NamespaceReconciler{
		Client: clusterMgr.GetClient(),
		Scheme: clusterMgr.GetScheme(),
	}

	if err := namespaceR.SetupWithManager(clusterMgr); err != nil {
		logs.Fatal(fmt.Sprintf("Unable to create Namespace controller: %s", err.Error()))
		os.Exit(1)
	}

	go func() {
		if err := clusterMgr.Start(ctx); err != nil {
			logs.Fatal(fmt.Sprintf("Problem running namespace manager: %s", err.Error()))
			os.Exit(1)
		}
		logs.Debugf("Starting cluster namespace manager")
	}()
}

func startTriggerInstanceController(ctx context.Context) {
	time.Sleep(time.Second * 5) // hack for order controller run, must refactor

	var renderTemplate = &creation.RenderController{}
	creation.RC = renderTemplate

	var watcherController = &creation.WatcherController{ReSyncPeriod: 5}
	watcherController.Start()

	var factoryController = &creation.FactoryController{}
	factoryController.Start()

	if strings.EqualFold(operator.CreationMode, "cluster") {
		opt := ctrl.Options{
			Logger:             Mgr.GetLogger(),
			Scheme:             Mgr.GetScheme(),
			WebhookServer:      webhook.NewServer(webhook.Options{Port: 9442}),
			MetricsBindAddress: "0",
		}

		clusterMgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), opt)
		if err != nil {
			logs.Fatal(fmt.Sprintf("Problem running ti manager: %s", err.Error()))
			os.Exit(1)
		}
		var triggerInstanceController operator.ReconcilerInterface = &controllers.TriggerInstanceReconciler{
			Client: clusterMgr.GetClient(),
			Scheme: clusterMgr.GetScheme(),
		}

		if err := triggerInstanceController.SetupWithManager(clusterMgr); err != nil {
			logs.Fatal(fmt.Sprintf("Unable to create TriggerInstance controller: %s", err.Error()))
			os.Exit(1)
		}

		go func() {
			if err := clusterMgr.Start(ctx); err != nil {
				logs.Fatal(fmt.Sprintf("Problem running ti manager: %s", err.Error()))
				os.Exit(1)
			}
			logs.Debugf("Starting cluster ti manager")
		}()
	} else {
		var triggerInstanceController operator.ReconcilerInterface = &controllers.TriggerInstanceReconciler{
			Client: Mgr.GetClient(),
			Scheme: Mgr.GetScheme(),
		}

		if err := triggerInstanceController.SetupWithManager(Mgr); err != nil {
			logs.Fatal(fmt.Sprintf("Unable to create TriggerInstance controller: %s", err.Error()))
			os.Exit(1)
		}
	}
}
